package fatworm.tx.recovery;

import fatworm.server.*;
import fatworm.storage.buffer.*;
import fatworm.storage.file.*;
import fatworm.storage.types.*;
import fatworm.tx.log.*;

class SetBytesRecord implements LogRecord
{
    private int txnum, offset;
    private byte[] val;
    private Block blk;

    /**
     * Creates a new setstring log record.
     * 
     * @param txnum
     *            the ID of the specified transaction
     * @param blk
     *            the block containing the value
     * @param offset
     *            the offset of the value in the block
     * @param val
     *            the new value
     */
    public SetBytesRecord(int txnum, Block blk, int offset, byte[] val)
    {
        this.txnum = txnum;
        this.blk = blk;
        this.offset = offset;
        this.val = val;
    }
    /**
     * Creates a log record by reading five other values from the log.
     * 
     * @param rec
     *            the basic log record
     */
    public SetBytesRecord(BasicLogRecord rec)
    {
        txnum = rec.nextInt();
        int len = rec.nextInt();
        byte[] fn_s = rec.nextBytes(len);
        String filename = new String(fn_s);
        int blknum = rec.nextInt();
        blk = new Block(filename, blknum);
        offset = rec.nextInt();
        len = rec.nextInt();
        val = rec.nextBytes(len);
    }
    /**
     * Writes a setString record to the log. This log record contains the
     * SETSTRING operator, followed by the transaction id, the filename, number,
     * and offset of the modified block, and the previous string value at that
     * offset.
     * 
     * @return the LSN of the last log value
     */
    public int writeToLog()
    {
        Object[] rec = new Object[]{SETSTRING, txnum, new JString(blk.filename), blk.blknum,
                offset, new JBytes(val)};
        return Fatworm.logMgr.append(rec);
    }
    public int op()
    {
        return SETSTRING;
    }
    public int txNumber()
    {
        return txnum;
    }
    public String toString()
    {
        return "<SETSTRING " + txnum + " " + blk + " " + offset + " " + val + ">";
    }
    /**
     * Replaces the specified data value with the value saved in the log record.
     * The method pins a buffer to the specified block, calls setString to
     * restore the saved value (using a dummy LSN), and unpins the buffer.
     * 
     * @see fatworm.tx.recovery.LogRecord#undo(int)
     */
    public void undo(int txnum)
    {
        BufferMgr buffMgr = Fatworm.bufferMgr;
        Buffer buff = buffMgr.pin(blk);
        buff.setBytes(offset, val, txnum, -1);
        buffMgr.unpin(buff);
    }
}
